package com.dlc.apk.core


import com.dlc.apk.entity.ShipmentProgress
import com.dlc.apk.util.LogPlus
import java.util.concurrent.ConcurrentHashMap

/**
 * 使用流程管理 对外封装过程并向外暴露结果
 * 不关心硬件协议实现以及数据上报,由外部实现
 */
class DeviceManager private constructor() {
    var hardwareControllerImpl: IHardwareController? = null
    var reportImpl: IReportListener? = null

    //正在进行中的任务
    val shipmentTaskMap: ConcurrentHashMap<Int, ShipmentProgress> = ConcurrentHashMap()

    private object InstanceHolder {
        val instance = DeviceManager()
    }

    fun init(hardwareControllerImpl: IHardwareController?, reportImpl: IReportListener?) {
        this.hardwareControllerImpl = hardwareControllerImpl
        this.reportImpl = reportImpl
        //处理队列"启动设备"任务
        initQueueTask()
    }


    private fun initQueueTask() {
        /*处理队列"出货"任务*/
        ShipmentTaskHandler.getInstance().handleTask(object : ShipmentTaskHandler.IShipment {
            override fun startShipment(shipmentTask: ShipmentTaskHandler.ShipmentTask) {
                val flowNo = shipmentTask.flowNo
                LogPlus.e("###执行出货->流水号->$flowNo")
                executeShipment(flowNo, shipmentTask.cargoNumberType, shipmentTask.actionCargoRowNumberOrNo1, shipmentTask.actionCargoColumnNumber1, shipmentTask.actionCargoRowNumberOrNo2, shipmentTask.actionCargoColumnNumber2, shipmentTask.actionCargoRowNumberOrNo3, shipmentTask.actionCargoColumnNumber3, shipmentTask.actionCargoRowNumberOrNo4, shipmentTask.actionCargoColumnNumber4, shipmentTask.actionCargoRowNumberOrNo5, shipmentTask.actionCargoColumnNumber5, shipmentTask.maxActionTime, shipmentTask.pickTimeOut, shipmentTask.theftBaffleTimeout)
            }

            override fun checkIsShipmentSuccessed(shipmentTask: ShipmentTaskHandler.ShipmentTask): Boolean {
                //检查当前流水号是否出货成功
                val isShipmentStateAllDone = shipmentTaskMap[shipmentTask.flowNo]?.shipmentState == ShipmentProgress.SHIPMENT_STATE_ALL_DONE
                if (isShipmentStateAllDone) {
                    val shipmentResult = shipmentTaskMap[shipmentTask.flowNo]?.shipmentResult
                    val errCode = shipmentTaskMap[shipmentTask.flowNo]?.errCode
                    shipmentTask.firstShipmentResult = shipmentResult ?: -1
                    shipmentTask.errCode = errCode ?: -1
                    LogPlus.e("###出货状态->$isShipmentStateAllDone, 掉货结果->$shipmentResult,errCode->$errCode")
                }
                return isShipmentStateAllDone
            }
        }, object : ShipmentTaskHandler.IShipmentTaskCallback {
            override fun onSuccess(shipmentTask: ShipmentTaskHandler.ShipmentTask) {
                //清除内存中已记录的流水任务
                shipmentTaskMap.remove(shipmentTask.flowNo)
                /*上报出货结果*/
                reportImpl?.onShipmentResult(shipmentTask.flowNo, true, shipmentTask.attachData, "出货成功")
            }

            override fun onFailed(shipmentTask: ShipmentTaskHandler.ShipmentTask, msg: String) {
                //清除内存中已记录的流水任务
                shipmentTaskMap.remove(shipmentTask.flowNo)
                /*上报出货结果*/
                reportImpl?.onShipmentResult(shipmentTask.flowNo, false, shipmentTask.attachData, "出货失败:$msg,结果->${shipmentTaskMap[shipmentTask.flowNo]}")
            }
        })
    }

    fun addShipmentTask(flowNo: Int, cargoNumberType: Int, actionCargoRowNumberOrNo1: Int, actionCargoColumnNumber1: Int, actionCargoRowNumberOrNo2: Int, actionCargoColumnNumber2: Int, actionCargoRowNumberOrNo3: Int, actionCargoColumnNumber3: Int, actionCargoRowNumberOrNo4: Int, actionCargoColumnNumber4: Int, actionCargoRowNumberOrNo5: Int, actionCargoColumnNumber5: Int, maxActionTime: Int, pickTimeOut: Int, theftBaffleTimeout: Int, attachData: Any? = null, shipmentTaskCallback: ShipmentTaskHandler.IShipmentTaskCallback) {
        //加入到"待出货"任务队列
        LogPlus.e("###attachdata->$attachData")
        val errCode = -1
        val firstShipmentResult = -1
        ShipmentTaskHandler.getInstance().put(
            ShipmentTaskHandler.ShipmentTask(flowNo, cargoNumberType, actionCargoRowNumberOrNo1, actionCargoColumnNumber1, actionCargoRowNumberOrNo2, actionCargoColumnNumber2, actionCargoRowNumberOrNo3, actionCargoColumnNumber3, actionCargoRowNumberOrNo4, actionCargoColumnNumber4, actionCargoRowNumberOrNo5, actionCargoColumnNumber5, maxActionTime, pickTimeOut, theftBaffleTimeout, attachData, 0, errCode, firstShipmentResult, object : ShipmentTaskHandler.IShipmentTaskCallback {
                override fun onSuccess(shipmentTask: ShipmentTaskHandler.ShipmentTask) {
                    shipmentTaskCallback.onSuccess(shipmentTask)
                }

                override fun onFailed(shipmentTask: ShipmentTaskHandler.ShipmentTask, msg: String) {
                    shipmentTaskCallback.onFailed(shipmentTask, msg)
                }
            })
        )
    }

    /**
     * 更新出货任务状态
     */
    fun updateTaskState(flowNo: Int, shipmentState: Int, currentStep: Int, errCode: Int, th1ShipmentResult: Int, th2ShipmentResult: Int, th3ShipmentResult: Int, th4ShipmentResult: Int, th5ShipmentResult: Int) {
        if (shipmentTaskMap[flowNo] == null) {
            //无当前流水的任务
            return
        }
        shipmentTaskMap[flowNo]?.shipmentState = shipmentState
        shipmentTaskMap[flowNo]?.currentStep = currentStep
        shipmentTaskMap[flowNo]?.errCode = errCode
        shipmentTaskMap[flowNo]?.shipmentResult = th1ShipmentResult
        LogPlus.e("###更新出货任务状态->${shipmentTaskMap[flowNo]}")
    }

    fun getLastShipmentTask(): ShipmentTaskHandler.ShipmentTask? {
        return ShipmentTaskHandler.getInstance().lastShipmentTask
    }

    /**
     * 执行硬件 出货
     */
    private fun executeShipment(flowNo: Int, cargoNumberType: Int, actionCargoRowNumberOrNo1: Int, actionCargoColumnNumber1: Int, actionCargoRowNumberOrNo2: Int, actionCargoColumnNumber2: Int, actionCargoRowNumberOrNo3: Int, actionCargoColumnNumber3: Int, actionCargoRowNumberOrNo4: Int, actionCargoColumnNumber4: Int, actionCargoRowNumberOrNo5: Int, actionCargoColumnNumber5: Int, maxActionTime: Int, pickTimeOut: Int, theftBaffleTimeout: Int) {
        val params = HashMap<String, Any>()
        params["cargoNumberType"] = cargoNumberType
        params["actionCargoRowNumberOrNo1"] = actionCargoRowNumberOrNo1
        params["actionCargoColumnNumber1"] = actionCargoColumnNumber1
        params["actionCargoRowNumberOrNo2"] = actionCargoRowNumberOrNo2
        params["actionCargoColumnNumber2"] = actionCargoColumnNumber2
        params["actionCargoRowNumberOrNo3"] = actionCargoRowNumberOrNo3
        params["actionCargoColumnNumber3"] = actionCargoColumnNumber3
        params["actionCargoRowNumberOrNo4"] = actionCargoRowNumberOrNo4
        params["actionCargoColumnNumber4"] = actionCargoColumnNumber4
        params["actionCargoRowNumberOrNo5"] = actionCargoRowNumberOrNo5
        params["actionCargoColumnNumber5"] = actionCargoColumnNumber5
        params["maxActionTime"] = maxActionTime
        params["pickTimeOut"] = pickTimeOut
        params["theftBaffleTimeout"] = theftBaffleTimeout
        hardwareControllerImpl?.startShipment(flowNo, params, object : IExecuteCallback {
            override fun onResponseSuccess(result: Boolean) {
                LogPlus.e("###应答成功,result->$result")
                shipmentTaskMap[flowNo] = ShipmentProgress(flowNo, ShipmentProgress.SHIPMENT_STATE_ING, -1, -1, -1)
                LogPlus.e("###任务进度初始数据->${shipmentTaskMap[flowNo]}")
            }

            override fun onResponseFailed(msg: String?) {
                LogPlus.e("###应答失败,msg->$msg")
            }
        })
    }

    companion object {
        val instance: DeviceManager
            get() = InstanceHolder.instance
    }
}